package com.xixi.dataStructure.stack; /**
 * /**
 * An animal shelter, which holds only dogs and cats, operates on a strictly"first
 * in, first out" basis. People must adopt either the"oldest" (based on arrival
 * time) of all animals at the shelter, or they can select whether they would prefer
 * a dog or a cat (and will receive the oldest animal of that type). They cannot
 * select which specific animal they would like. Create the data structures to
 * maintain this system and implement operations such as enqueue, dequeueAny, dequeueDog,
 * and dequeueCat. You may use the built-in Linked list data structure.
 * <p>
 * enqueue method has a animal parameter, animal[0] represents the number of the
 * animal, animal[1] represents the type of the animal, 0 for cat and 1 for dog.
 * <p>
 * dequeue* method returns [animal number, animal type], if there's no animal
 * that can be adopted, return [-1, -1].
 * <p>
 * Example1:
 * <p>
 * <p>
 * Input:
 * ["AnimalShelf", "enqueue", "enqueue", "dequeueCat", "dequeueDog", "dequeueAny"]
 * [[], [[0, 0]], [[1, 0]], [], [], []]
 * Output:
 * [null,null,null,[0,0],[-1,-1],[1,0]]
 * <p>
 * <p>
 * Example2:
 * <p>
 * <p>
 * Input:
 * ["AnimalShelf", "enqueue", "enqueue", "enqueue", "dequeueDog", "dequeueCat",
 * "dequeueAny"]
 * [[], [[0, 0]], [[1, 0]], [[2, 1]], [], [], []]
 * Output:
 * [null,null,null,null,[2,1],[0,0],[1,0]]
 * <p>
 * <p>
 * Note:
 * <p>
 * <p>
 * The number of animals in the shelter will not exceed 20000.
 * <p>
 * <p>
 * Related Topics 设计 队列 👍 46 👎 0
 */

import java.util.Stack;

public class ID_interview_03_06_AnimalShelterLcci {
    public static void main(String[] args) {
        AnimalShelf solution = new ID_interview_03_06_AnimalShelterLcci().new AnimalShelf();
    }


    //leetcode submit region begin(Prohibit modification and deletion)
    class AnimalShelf {

        Stack<Integer> catIn = new Stack<>();
        Stack<Integer> catOut = new Stack<>();
        Stack<Integer> dogIn = new Stack<>();
        Stack<Integer> dogOut = new Stack<>();


        public AnimalShelf() {

        }

        public void enqueue(int[] animal) {
            switch (animal[1]) {
                case 0:
                    if (!catOut.isEmpty()) {
                        this.transfer(catOut, catIn); //move outstack into the instack make sure newest on the top
                    }
                    catIn.push(animal[0]);
                    break;
                case 1:
                    if (!dogOut.isEmpty()) {
                        this.transfer(dogOut, dogIn); //move outstack into the instack make sure newest on the top
                    }
                    dogIn.push(animal[0]);
                    break;
            }


        }

        public int[] dequeueAny() {
            if (dogOut.isEmpty()) {
                this.transfer(dogIn, dogOut); //dequeue make sure oldest on the top
            }

            if (catOut.isEmpty()) {
                this.transfer(catIn, catOut); //dequeue make sure oldest on the top
            }
            if (dogOut.isEmpty() && catOut.isEmpty()) {
                return new int[]{-1, -1};
            } else if (!dogOut.isEmpty() && catOut.isEmpty()) {
                return new int[]{dogOut.pop(), 1};
            } else if (dogOut.isEmpty()) {
                return new int[]{catOut.pop(), 0};
            }


            if (catOut.peek() < dogOut.peek()) {
                return new int[]{catOut.pop(), 0};
            } else {
                return new int[]{dogOut.pop(), 1};
            }


        }

        public int[] dequeueDog() {
            if (dogOut.isEmpty()) {
                this.transfer(dogIn, dogOut); //dequeue make sure oldest on the top
            }
            if (dogOut.isEmpty()) {
                return new int[]{-1, -1};
            }
            return new int[]{dogOut.pop(), 1};
        }

        public int[] dequeueCat() {
            if (catOut.isEmpty()) {
                this.transfer(catIn, catOut); //dequeue make sure oldest on the top
            }
            if (catOut.isEmpty()) {
                return new int[]{-1, -1};
            }
            return new int[]{catOut.pop(), 0};
        }

        private void transfer(Stack<Integer> from, Stack<Integer> to) {

            while (!from.isEmpty()) {
                to.push(from.pop());
            }


        }

    }

/**
 * Your AnimalShelf object will be instantiated and called as such:
 * AnimalShelf obj = new AnimalShelf();
 * obj.enqueue(animal);
 * int[] param_2 = obj.dequeueAny();
 * int[] param_3 = obj.dequeueDog();
 * int[] param_4 = obj.dequeueCat();
 */
//leetcode submit region end(Prohibit modification and deletion)


}